﻿// <copyright file="MySpacePeopleRequest.cs" company="Microsoft Corporation">
// Copyright (c) 2009 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2008-10-07</date>
// <summary>CLR Object for MySpace Videos Silverlight data binding</summary>

namespace MyOpenSpace
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows.Browser;
    using System.Windows.Media.Imaging;
    using Synergist;

    /// <summary>
    /// MySpace Videos CLR object to be used in Silverlight Data Binding
    /// </summary>
    public class MySpacePeopleRequest : INotifyPropertyChanged
    {
        #region Fields
        /// <summary>
        /// the ID to query
        /// </summary>
        private string idSpec;

        /// <summary>
        /// the 1-based start index of the items to get
        /// </summary>
        private int startIndex = 1;

        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the MySpacePeopleRequest class.
        /// </summary>
        public MySpacePeopleRequest()
        {
            this.People = new ObservableCollection<MyOpenSpace.Person>();
            this.Max = int.MaxValue;
            this.PageSize = 20;
        }
        #endregion

        #region Events
        /// <summary>
        /// property changed event
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Properties
        /// <summary>
        /// Gets the start index of this page from the collection
        /// </summary>
        [Description("The 1-based starting index of this page from the collection.")]
        public int StartIndex 
        { 
            get
            {
                return this.startIndex;
            }

            private set
            {
                this.startIndex = value;

                if (value == 1)
                {
                    this.People.Clear();
                }

                this.FetchItems();

                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("StartIndex"));
                }
            }
        }

        /// <summary>
        /// Gets or sets the maximum total number of results to return (default is int.Max)
        /// </summary>
        [Description("The maximum number of friends to request.")]
        public int Max { get; set; }

        /// <summary>
        /// Gets or sets the page size in number of results (default is 20)
        /// </summary>
        [Description("The number of friends to request in each call.")]
        public int PageSize { get; set; }

        /// <summary>
        /// Gets or sets the entity to query (opensocial.IdSpec.PersonId.OWNER for owner's friends, opensocial.IdSpec.PersonId.VIEWER for viewer's friends)
        /// </summary>
        [Description("opensocial.IdSpec.PersonId.OWNER for the owner's friends\nopensocial.IdSpec.PersonId.VIEWER for viewer's friends")]
        public string IdSpec
        {
            get
            {
                return this.idSpec;
            }

            set
            {
                this.idSpec = value;

                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("IdSpec"));
                }

                this.StartIndex = 1;
            }
        }

        /// <summary>
        /// Gets the person collection
        /// </summary>
        /// <remarks>When in design mode, it returns a list of three sample Person objects (they are identical)</remarks>
        [Description("the person collection")]
        public ObservableCollection<MyOpenSpace.Person> People { get; private set; }
        #endregion

        #region Implementation
        /// <summary>
        /// Fetch the items
        /// </summary>
        private void FetchItems()
        {
            if (!HtmlPage.IsEnabled)
            {
                this.AddSampleData();

                return;
            }

            var os = opensocial.Container.get();

            if (os == null)
            {
                this.AddSampleData();

                return;
            }

            var dataRequest = os.newDataRequest();

            var friends = new opensocial.IdSpec()
            {
                UserId = this.IdSpec.Eval(),
                NetworkDistance = 1,
            };

            var parameters = HtmlPage.Window.Eval("new Array()") as ScriptObject;

            parameters.SetProperty("opensocial.DataRequest.PeopleRequestFields.FIRST".Eval(), System.Convert.ToDouble(this.StartIndex));
            parameters.SetProperty("opensocial.DataRequest.PeopleRequestFields.MAX".Eval(), System.Convert.ToDouble(this.PageSize));

            var request = dataRequest.newFetchPeopleRequest(friends, parameters);

            dataRequest.add(request, this.IdSpec.Eval() + "_friends");

            System.Diagnostics.Debug.WriteLine("Sending Fetch People Reuest for {0} friends.", this.IdSpec.Eval());

            dataRequest.send(new opensocial.DataReceived(this.OnDataReceived));
        }

        /// <summary>
        /// People are returned from MySpace
        /// </summary>
        /// <param name="response">the response from the web service call</param>
        private void OnDataReceived(opensocial.DataResponse response)
        {
            if (response.HadError)
            {
                System.Diagnostics.Debug.WriteLine("Error retreiving friends for {0}: {1}", this.IdSpec.Eval(), response.ErrorMessage);

                return;
            }

            var data = response.get(this.IdSpec.Eval() + "_friends").getData();

            var collection = new opensocial.Collection(data);

            var totalSize = collection.getTotalSize();

            var peopleReturned = collection.asArray();

            var personCollection = from scriptObject in peopleReturned
                                   select new MyOpenSpace.Person(scriptObject);

            foreach (var person in personCollection)
            {
                this.People.Add(person);
            }

            if (this.People.Count < totalSize && this.People.Count < this.Max)
            {
                this.StartIndex += this.PageSize;
            }
        }

        /// <summary>
        /// Add sample data
        /// </summary>
        private void AddSampleData()
        {
            if (this.People.Count > 0)
            {
                return;
            }

            const int Batches = 20;

            for (var i = 0; i < Batches; i++)
            {
                var samples = new MyOpenSpace.Person[]
                {
                    new MyOpenSpace.Person() 
                    { 
                        DisplayName = "Tom", 
                        Nickname = "Tom", 
                        ProfileUrl = new Uri("http://www.myspace.com/tom", UriKind.Absolute),
                        ThumbnailImage = new BitmapImage(new Uri(Properties.Resources.PersonThumbnailUrl, UriKind.Absolute)) 
                    },
                    new MyOpenSpace.Person() 
                    { 
                        DisplayName = "MySpace Developer Platform", 
                        Nickname = "MySpace Developer Platform", 
                        ProfileUrl = new Uri("http://www.myspace.com/myspacedeveloperplatform", UriKind.Absolute),
                        ThumbnailImage = new BitmapImage(new Uri("http://c4.ac-images.myspacecdn.com/images02/105/s_16989d4593ab4c70af2a0d620e37e5fb.jpg", UriKind.Absolute)) 
                    },
                    new MyOpenSpace.Person() 
                    { 
                        DisplayName = "Silverlight on MySpace", 
                        Nickname = "Silverlight on MySpace", 
                        ProfileUrl = new Uri("http://www.myspace.com/silverlightonmyspace", UriKind.Absolute),
                    },
                    new MyOpenSpace.Person() 
                    { 
                        DisplayName = "Michael S. Scherotter", 
                        Nickname = "Michael S. Scherotter", 
                        ProfileUrl = new Uri("http://www.myspace.com/ms_synergist", UriKind.Absolute), 
                        ThumbnailImage = new BitmapImage(new Uri("http://c3.ac-images.myspacecdn.com/images02/112/m_3ccd7d71afaa467795c8a5a2d68317a6.jpg", UriKind.Absolute)) 
                    },
                };

                foreach (var sample in samples)
                {
                    this.People.Add(sample);
                }
            }
        }
        #endregion
    }
}
